﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.LIB;
using YArchitech.Revit;

namespace YArchitech.Plumbing
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class SpraySystemCal : DrainageSystemCal
	{
		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public override Result HYExecute()
		{
			HYSystemCal hysystemCal = new HYSystemCal();
			SearchSys searchSys = new SearchSys();
			string prompt = "请选择要计算分支的入口管道远端: ";
			if (!searchSys.Run(base.UiDoc, prompt))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			searchSys.DumpIntoPipeSystem(out hysystemCal, base.UiDoc.Document);
			hysystemCal.systemType = HYSystemCal.SystemType.Spraying;
			base.GetPipeDNForPipe(hysystemCal);
			hysystemCal.ClearSprinklerSelected();
			ElementSet elementSet = new ElementSet();
			TextNote textNote = null;
			this.ErasePolygonLinesAndTextNote(base.Doc, ref elementSet, ref textNote);
			double deffectArea = this.DrawPolygonArea(base.UiDoc, hysystemCal, ref elementSet, ref textNote);
			SprayCalDialog sprayCalDialog = new SprayCalDialog(base.Doc, base.UiDoc, hysystemCal);
			sprayCalDialog.deffectArea = deffectArea;
			for (;;)
			{
				DialogResult dialogResult = sprayCalDialog.ShowDialog();
				if (dialogResult == DialogResult.Abort)
				{
					if (sprayCalDialog.beMinimize)
					{
						base.BeMinimizeOperator(base.UiDoc, sprayCalDialog.elemIds);
						continue;
					}
					try
					{
						this.ErasePolygonLinesAndTextNote(base.Doc, ref elementSet, ref textNote);
						hysystemCal = new HYSystemCal();
						searchSys = new SearchSys();
						if (!searchSys.Run(base.UiDoc, prompt))
						{
							return Autodesk.Revit.UI.Result.Cancelled;
						}
						searchSys.DumpIntoPipeSystem(out hysystemCal, base.UiDoc.Document);
						hysystemCal.systemType = HYSystemCal.SystemType.Spraying;
						base.GetPipeDNForPipe(hysystemCal);
						hysystemCal.ClearSprinklerSelected();
						deffectArea = this.DrawPolygonArea(base.UiDoc, hysystemCal, ref elementSet, ref textNote);
						sprayCalDialog.deffectArea = deffectArea;
						sprayCalDialog.hySystemCal = hysystemCal;
						continue;
					}
					catch (Exception ex)
					{
						YJKMessageBox.Show(ex.Message);
						continue;
					}
				}
				if (dialogResult != DialogResult.OK)
				{
					break;
				}
				hysystemCal = new HYSystemCal();
				hysystemCal = sprayCalDialog.hySystemCal;
				bool flag = false;
				flag = base.ReturnDataToDocument(hysystemCal.PipeCals, "喷淋计算");
				flag &= this.ClearAllSprinklersFlow(hysystemCal.PipeCals);
				foreach (HYPipeCal hypipeCal in hysystemCal.PipeCals)
				{
					if (hypipeCal.endSprinkler != null && hypipeCal.endSprinkler.IsInArea)
					{
						hypipeCal.endSprinkler.Flow = hypipeCal.Flow;
						Element element = base.Doc.GetElement(new ElementId(hypipeCal.endSprinkler.Id));
						if (element != null)
						{
							flag &= RevitUtils.WriteFlowToSprinkler(element, hypipeCal.endSprinkler.Flow);
						}
					}
				}
				if (flag)
				{
					YJKMessageBox.Information("赋回成功");
				}
			}
			this.ErasePolygonLinesAndTextNote(base.Doc, ref elementSet, ref textNote);
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public override void FilterProcess()
		{
            base.FilterViewType.Add((Autodesk.Revit.DB.ViewType)1);
            base.FilterViewType.Add((Autodesk.Revit.DB.ViewType)2);
		}

		protected double DrawPolygonArea(UIDocument uiDoc, HYSystemCal systemCal, ref ElementSet polygonLines, ref TextNote textNote)
		{
			Document document = uiDoc.Document;
			double num = 0.0;
			polygonLines.Clear();
			Transaction transaction = new Transaction(document, "绘制多边形区域");
			transaction.Start();
			Selection selection = uiDoc.Selection;
			FormSelectedAreaInfo formSelectedAreaInfo = null;
			try
			{
				XYZ xyz = selection.PickPoint("请选择绘制最不利作用区域的第一个点……");
				XYZ xyz2 = new XYZ(xyz.X, xyz.Y, xyz.Z);
				XYZ xyz3 = new XYZ(xyz.X, xyz.Y, xyz.Z);
				List<XYZ> list = new List<XYZ>();
				list.Add(xyz);
				if (SpraySystemCal.hWndRevit == null)
				{
					SpraySystemCal.hWndRevit = new YJKWindowHandle(Process.GetCurrentProcess().MainWindowHandle);
				}
				formSelectedAreaInfo = new FormSelectedAreaInfo();
				formSelectedAreaInfo.Show(SpraySystemCal.hWndRevit);
				int wMsg = 7;
				SpraySystemCal.SendMessage(SpraySystemCal.hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
				for (;;)
				{
					try
					{
						xyz3 = selection.PickPoint("右键取消或ESC退出 /选择下一点:");
						if (xyz.IsAlmostEqualTo(xyz3))
						{
							YJKMessageBox.Error("不能选择两个重合的点！");
						}
						else
						{
							list.Add(xyz3);
							DetailLine detailLine = YJKRevitTools.DrawDetailLine(document, xyz, xyz3);
							polygonLines.Insert(detailLine);
							xyz = xyz3;
							if (list.Count > 2)
							{
								num = Math.Round(YJKRevitTools.CalArea(list) * 0.3048 * 0.3048, 3);
								if (formSelectedAreaInfo != null && formSelectedAreaInfo.Visible)
								{
									formSelectedAreaInfo.textBoxArea.Text = string.Format("{0}", num.ToString());
								}
							}
							if (list.Count <= 2 || !xyz2.IsAlmostEqualTo(xyz3))
							{
								continue;
							}
							foreach (HYPipeCal hypipeCal in systemCal.PipeCals)
							{
								if (hypipeCal.endSprinkler != null && YJKRevitTools.Contains(hypipeCal.endSprinkler.Location, list))
								{
									hypipeCal.endSprinkler.IsInArea = true;
								}
							}
							num = Math.Round(YJKRevitTools.CalArea(list) * 0.3048 * 0.3048, 3);
							XYZ origin = new XYZ(xyz2.X + 1.0, xyz2.Y - 1.0, xyz2.Z);
                            textNote = document.GetTextNode(document.ActiveView, origin, XYZ.BasisX, XYZ.BasisY, 0.24384000000000003, (TextAlignFlags)64, "面积：" + num + " m^2");
							document.Regenerate();
							transaction.Commit();
						}
					}
                    catch (Autodesk.Revit.Exceptions.OperationCanceledException ex)
					{
						ex.ToString();
						if (list.Count > 2)
						{
							DetailLine detailLine2 = YJKRevitTools.DrawDetailLine(document, xyz3, xyz2);
							polygonLines.Insert(detailLine2);
							foreach (HYPipeCal hypipeCal2 in systemCal.PipeCals)
							{
								if (hypipeCal2.endSprinkler != null && YJKRevitTools.Contains(hypipeCal2.endSprinkler.Location, list))
								{
									hypipeCal2.endSprinkler.IsInArea = true;
								}
							}
							num = Math.Round(YJKRevitTools.CalArea(list) * 0.3048 * 0.3048, 3);
							XYZ origin2 = new XYZ(xyz2.X + 1.0, xyz2.Y - 1.0, xyz2.Z);
                            textNote = document.GetTextNode(document.ActiveView, origin2, XYZ.BasisX, XYZ.BasisY, 0.24384000000000003, (TextAlignFlags)64, "面积：" + num + " m^2");
							document.Regenerate();
							transaction.Commit();
						}
					}
					catch (Exception ex2)
					{
						ex2.ToString();
					}
					break;
				}
			}
			catch (Exception ex3)
			{
				ex3.ToString();
			}
			finally
			{
				if (transaction != null && transaction.GetStatus() != (TransactionStatus)3)
				{
					transaction.RollBack();
					polygonLines.Clear();
				}
			}
			if (formSelectedAreaInfo != null && formSelectedAreaInfo.Visible)
			{
				formSelectedAreaInfo.Close();
			}
			return num;
		}

		protected bool ErasePolygonLinesAndTextNote(Document doc, ref ElementSet lines, ref TextNote textNote)
		{
			Transaction transaction = new Transaction(doc, "删除多边形区域");
			transaction.Start();
			try
			{
				if (lines.Size > 0)
				{
					IEnumerator enumerator = lines.GetEnumerator();
					bool flag = enumerator.MoveNext();
					while (flag)
					{
						Element element = enumerator.Current as Element;
						if (element != null && doc.GetElement(element.Id) != null)
						{
							doc.Delete(element.Id);
						}
						flag = enumerator.MoveNext();
					}
					lines.Clear();
				}
				if (textNote != null)
				{
					doc.Delete(textNote.Id);
					textNote = null;
				}
				doc.Regenerate();
				transaction.Commit();
			}
			catch (Exception ex)
			{
				ex.ToString();
			}
			finally
			{
				if (transaction != null && transaction.GetStatus() != (TransactionStatus)3)
				{
					transaction.RollBack();
				}
			}
			return true;
		}

		protected bool ClearAllSprinklersFlow(List<HYPipeCal> pipes)
		{
			bool flag = true;
			double flow = 0.0;
			foreach (HYPipeCal hypipeCal in pipes)
			{
				if (hypipeCal.endSprinkler != null)
				{
					Element element = base.Doc.GetElement(new ElementId(hypipeCal.endSprinkler.Id));
					if (element != null)
					{
						flag &= RevitUtils.WriteFlowToSprinkler(element, flow);
					}
				}
			}
			return flag;
		}

		public static YJKWindowHandle hWndRevit;
	}
}
